package com.hangan.langchainspringstart.config;

import com.hangan.langchainspringstart.repository.RedisChatMemoryStore;
import dev.langchain4j.data.document.Document;
import dev.langchain4j.data.document.loader.ClassPathDocumentLoader;
import dev.langchain4j.data.document.parser.apache.pdfbox.ApachePdfBoxDocumentParser;
import dev.langchain4j.data.segment.TextSegment;
import dev.langchain4j.internal.ValidationUtils;
import dev.langchain4j.memory.ChatMemory;
import dev.langchain4j.memory.chat.ChatMemoryProvider;
import dev.langchain4j.memory.chat.MessageWindowChatMemory;
import dev.langchain4j.model.embedding.EmbeddingModel;
import dev.langchain4j.rag.content.retriever.ContentRetriever;
import dev.langchain4j.rag.content.retriever.EmbeddingStoreContentRetriever;
import dev.langchain4j.store.embedding.EmbeddingStore;
import dev.langchain4j.store.embedding.EmbeddingStoreIngestor;
import dev.langchain4j.store.embedding.inmemory.InMemoryEmbeddingStore;
import lombok.RequiredArgsConstructor;
import org.apache.commons.lang3.ClassPathUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;

import java.math.BigDecimal;
import java.util.List;

/**
 * @author hang an
 * @since 2025/7/29
 */
@Configuration
@RequiredArgsConstructor
public class CommonConfig {

    private final RedisChatMemoryStore redisChatMemoryStore;
    private final EmbeddingModel embeddingModel;
    // 构建会话记忆对象
    @Bean
    public ChatMemory chatMemory() {
        return MessageWindowChatMemory.builder()
                .maxMessages(20) // 最大保存的消息数
                .build();
    }

    // 构建ChatMemoryProvider
    @Bean
    public ChatMemoryProvider chatMemoryProvider() {
        return id -> MessageWindowChatMemory.builder()
                .id(id) // 会话id
                .maxMessages(20) // 最大保存的消息数
                .chatMemoryStore(redisChatMemoryStore) // 会话记忆存储对象
                .build();
    }


    // 构建向量数据库操作对象
    @Bean
    public EmbeddingStore<TextSegment> embeddingStore() {
        // 加载文档到内存
        List<Document> documents = ClassPathDocumentLoader.loadDocuments("content",new ApachePdfBoxDocumentParser());
        // 构建向量数据库操作对象
        InMemoryEmbeddingStore<TextSegment> store = new InMemoryEmbeddingStore<>();
        // 构建一个EmbeddingStoreIngestor对象,完成文档文本的切割,向量化,存储
        EmbeddingStoreIngestor ingestor = EmbeddingStoreIngestor.builder()
                .embeddingStore(store)
                .embeddingModel(embeddingModel)
                .build();
        ingestor.ingest(documents);
        return store;
    }

    // 构建向量数据库检索对象
    @Bean
    public ContentRetriever contentRetriever(EmbeddingStore<TextSegment> embeddingStore) {
        return EmbeddingStoreContentRetriever.builder()
                .embeddingStore(embeddingStore) // 指定向量数据库
                .minScore(0.5) // 指定最小分数(余弦相似度)
                .maxResults(3) // 指定最大结果数
                .embeddingModel(embeddingModel)
                .build();
    }

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

}
